package cn.imatu.framework.data.mate.fieldbind;

import cn.hutool.core.util.StrUtil;
import cn.imatu.framework.data.mate.fieldbind.model.FieldDefine;
import cn.imatu.framework.tool.core.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 获取原字段值
 * @param <T> 注解所在字段类型
 * @author shenguangyang
 */
@SuppressWarnings("all")
public interface GetSourceFieldValueHandler<T> {

    /**
     * 对传入的字段值进行转换
     */
    List<?> getValue(Object value, FieldDefine fieldDefine);

    @Component
    class StringType implements GetSourceFieldValueHandler<String> {

        @Override
        public List<?> getValue(Object value, FieldDefine fieldDefine) {
            String delimiter = fieldDefine.getAnnotationMetadata().getDelimiter();
            if (StringUtils.isNotEmpty(delimiter)) {
                return StrUtil.split((String) value, delimiter);
            }
            return Collections.singletonList(value);
        }
    }

    @Component
    class IntegerType implements GetSourceFieldValueHandler<Integer> {

        @Override
        public List<?> getValue(Object value, FieldDefine fieldDefine) {
            if (Objects.isNull(value)) {
                return Collections.emptyList();
            }
            return Collections.singletonList(value);
        }
    }

    @Component
    class IntegerArray implements GetSourceFieldValueHandler<Integer[]> {

        @Override
        public List<?> getValue(Object value, FieldDefine fieldDefine) {
            Integer[] v = (Integer[]) value;
            return Arrays.stream(v).map(String::valueOf).collect(Collectors.toList());
        }
    }

    @Component
    class IntegerList implements GetSourceFieldValueHandler<List<Integer>> {

        @Override
        public List<?> getValue(Object value, FieldDefine fieldDefine) {
            List<Integer> v = (List<Integer>) value;
            return v.stream().map(String::valueOf).collect(Collectors.toList());
        }
    }

    @Component
    class StringList implements GetSourceFieldValueHandler<List<String>> {

        @Override
        public List<?> getValue(Object value, FieldDefine fieldDefine) {
            return (List<?>) value;
        }
    }

    @Component
    class StringSet implements GetSourceFieldValueHandler<Set<String>> {

        @Override
        public List<?> getValue(Object value, FieldDefine fieldDefine) {
            return new ArrayList<>(((Set<String>) value));
        }
    }
}
